package com.hp.bon.sgw.wh.channel.outside;

import com.alibaba.fastjson.JSON;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alipay.api.internal.util.StringUtils;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.wh.channel.common.BizConsts;
import com.hp.bon.sgw.wh.channel.common.BizParam;
import com.hp.bon.sgw.wh.channel.common.BizResult;
import com.hp.bon.sgw.wh.channel.outside.bizSlotOutQuery.utils.XmlMessageUtils;
import com.hp.bon.sgw.wh.service.UserResourceConfigService;

public class OutApiBizProcedure {

    private static final Logger _log = LoggerFactory.getLogger(OutApiBizProcedure.class);

    // private UserResourceConfigService urcService;
    private OutApiConfigLoader outApiConfigLoader;
    private OutApiBizRouter outApiBizRouter;
    private OutApiResponsor outApiResponsor;

    private static OutApiBizProcedure outApiBizProcedure;

    public static OutApiBizProcedure instance() {
        if (null == outApiBizProcedure) {
            outApiBizProcedure = new OutApiBizProcedure();
            outApiBizProcedure.init();
        }
        return outApiBizProcedure;
    }

    private void init() {
        //
        outApiConfigLoader = new OutApiConfigLoader();
        //
        outApiBizRouter = new OutApiBizRouter();
        outApiBizRouter.init();
        //
        outApiResponsor = new OutApiResponsor();
    }

    public String doProcedure(XmlMessage xmlMessage, Request request, Response response, long startTime) {
        //打印请求信息
        _log.info("out request is {}", xmlMessage.getDATA());

        BizParam bizParam = new BizParam();

        // 读配置控制参数
        String capability = XmlMessageUtils.getCapability(xmlMessage);
        bizParam.setParam(BizConsts.KEY_API_CAPABILITY, capability);
        _log.info("capability={}", capability);

        // 步骤1： 判断zw_falg 0走老流程,1走新流程
        int zw_flag = UserResourceConfigService.getIntValue("zw_flag", 0);
        _log.info("zw_flag={}", zw_flag);
        if (zw_flag == 0) {
            // 走现在的流程和调用 (老流程)
            return BizConsts.TYPE_ORIG_FLOW;
        }

        // 步骤2.检查能力是否在新账务中心接口范围之内
        _log.info("OutApiCapabilities={}", OutApiCapabilities.listOutApiCapabilities());
        if (!OutApiCapabilities.hasCapability(capability)) {
            _log.info("capability={} use old flow", capability);
            return BizConsts.TYPE_ORIG_FLOW;
        }

        // 步骤3.检查是否要调用新帐务中心接口，否则返回：BizConsts.TYPE_ORIG_FLOW
        _log.info("zwLatnCapability={}", OutApiCapabilities.listZwLatnCcapabilities());
        // ZwLatnCcapabilities中的能力不是通过zw_area_code判断是否走新接口，而是采用zw_latn
        if (OutApiCapabilities.zwLatnCapability(capability)) {
            // 从请求参数中获取{REGION_ID}, ZwLatnCcapabilities中的能力不是通过
            String zwLatn = UserResourceConfigService.getValue("zw_latn");
            _log.info("zw_latn={}", zwLatn);
            if (StringUtils.isEmpty(zwLatn)) {
                return BizConsts.TYPE_ORIG_FLOW;
            }

            String regionId = XmlMessageUtils.getRegionId(xmlMessage);
            _log.info("regionId={}", regionId);
            if (!(zwLatn.equals("888") || zwLatn.indexOf(regionId) >= 0)) {
                return BizConsts.TYPE_ORIG_FLOW;
            }
        } else {
            String areaCode = XmlMessageUtils.getAREACODE(xmlMessage);
            _log.info("/Service_Information/AREA_CODE={}", areaCode);
            // 通过zw_area_code判断是否走新接口
            String zwAreaCode = UserResourceConfigService.getValue("zw_area_code");
            _log.info("zw_area_code={}", zwAreaCode);
            if (StringUtils.isEmpty(zwAreaCode)) {
                return BizConsts.TYPE_ORIG_FLOW;
            }
            if (!(zwAreaCode.equals("888") || zwAreaCode.indexOf(areaCode) >= 0)) {
                return BizConsts.TYPE_ORIG_FLOW;
            }
        }

        // 步骤4. 加载配置信息
        bizParam = outApiConfigLoader.doLoader(bizParam);

        // 步骤5.路由到对应的业务处理：BizSlot
        // doRouter不允许向外抛异常
        BizSlot bizSlot = outApiBizRouter.doRouter(bizParam);
        if (null == bizSlot) {
            if (OutApiCapabilities.isWSCapability(capability)) {
                outApiResponsor.doResponseWSError(response, xmlMessage.getMID(), 11009, "bizSlotRouterNone");
            } else if (OutApiCapabilities.isHttpCapability(capability)) {
                outApiResponsor.doResponseStandardHttpError(response, "", "11104", "bizSlotRouterNone", "");
            } else {
                outApiResponsor.doResponseError(response, "invalid request, bizSlot none.");
            }
            return BizConsts.TYPE_ERROR_FLOW;
        }

        // 步骤6：路由到请求对应的处理类：slot,做业务处理(调用新帐务中心接口)
        // doBiz不允许向外抛异常
        BizResult bizResult = bizSlot.doBiz(xmlMessage, bizParam);
        _log.info("out response is {}", JSON.toJSONString(bizResult));
        // 步骤7：响应外部
        // doResponse 不允许向外抛异常
        try {
            if (bizResult.getCode() != null && bizResult.getCode().equals(BizConsts.STATUS_ACOUNT_API_FAIL)) {
                outApiResponsor.doResponseWSError(response, "", 400, "Unknown error in request");
            } else {
                outApiResponsor.doResponse(bizResult, response);
            }
        } catch (Exception e) {
            _log.info("exception is {}", e.toString());
        }

        // 步骤8：记录请求日志信息
        // TODO ...

        return BizConsts.TYPE_FINE_FLOW;
    }

}
